package com.scnu.common.config.web;


import com.scnu.common.constants.HttpCodeConstants;
import com.scnu.common.constants.HttpStatusConstants;
import com.scnu.common.exception.BaseException;
import com.scnu.common.result.Result;
import com.scnu.common.utils.StringUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.validation.FieldError;
import org.springframework.web.HttpRequestMethodNotSupportedException;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.MissingServletRequestParameterException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.method.annotation.MethodArgumentTypeMismatchException;

import javax.servlet.http.HttpServletRequest;


/**
 * 全局异常处理器
 *
 * @author ruoyi
 */
@RestControllerAdvice
@Slf4j
public class GlobalExceptionHandler
{

/*    *//**
     * 权限校验异常
     *//*
    @ExceptionHandler(AccessDeniedException.class)
    public AjaxResult handleAccessDeniedException(AccessDeniedException e, HttpServletRequest request)
    {
        String requestURI = request.getRequestURI();
        log.error("请求地址'{}',权限校验失败'{}'", requestURI, e.getMessage());
        return AjaxResult.error(HttpStatus.FORBIDDEN, "没有权限，请联系管理员授权");
    }*/

    /**
     * 请求方式不支持
     */
    @ExceptionHandler(HttpRequestMethodNotSupportedException.class)
    public Result handleHttpRequestMethodNotSupported(HttpRequestMethodNotSupportedException e,
                                                      HttpServletRequest request)
    {
        String requestURI = request.getRequestURI();
        log.error("请求地址'{}',不支持'{}'请求", requestURI, e.getMethod());
        return Result.error(HttpCodeConstants.BAD_REQUEST,"该请求地址不支持'"+e.getMethod()+"'请求");
    }
    @ExceptionHandler(HttpMessageNotReadableException.class)
    public Result handleHttpMessageNotReadable(HttpMessageNotReadableException e) {
        return Result.error(HttpStatusConstants.BAD_REQUEST,"请求体缺失或格式错误，请检查请求体的格式是否正确！");
    }

    @ExceptionHandler(MethodArgumentTypeMismatchException.class)
    public Result handleHttpMessageNotReadable(MethodArgumentTypeMismatchException e) {
        System.out.println(e);
        return Result.error(HttpStatusConstants.BAD_REQUEST,"请求参数格式错误，请检查该参数的格式："+e.getName());
    }

    /**
     * 业务异常
     */
    @ExceptionHandler(BaseException.class)
    public Result handleBaseException(BaseException e)
    {
//        log.error(e.getMessage(), e);
        if (e.getThrowable()!=null){
            log.error(e.getThrowable().getMessage());
        }
        if (StringUtils.isEmpty(e.getMessage())){
            e.setMessage("未知的业务异常");
        }


        Integer code = e.getCode();
        if (code!=null){
            return Result.error(code, e.getMessage());
        }
        return Result.error(e.getMessage());
    }

    /**
     * 参数校验异常
     * @param e
     * @return
     */
    @ExceptionHandler(MethodArgumentNotValidException.class)
    public Result handleMethodValidException(MethodArgumentNotValidException e)
    {

        // 从异常中提取字段错误信息
        FieldError fieldError = e.getBindingResult().getFieldError();
        String fieldName = fieldError.getField();      // 获取校验失败的字段名
        String errorMsg = fieldError.getDefaultMessage(); // 获取错误信息（如"学号不能为空"）

        return Result.error(HttpStatusConstants.BAD_REQUEST,String.format("参数校验失败: 字段[%s], 原因: %s", fieldName, errorMsg));
    }

    @ExceptionHandler(MissingServletRequestParameterException.class)
    public Result handleMethodValidException(MissingServletRequestParameterException e)
    {

        System.out.println(e);
/*        String fieldName = fieldError.getField();      // 获取校验失败的字段名
        String errorMsg = fieldError.getDefaultMessage(); // 获取错误信息（如"学号不能为空"）*/

        return Result.error(HttpStatusConstants.BAD_REQUEST,"参数不完整："+e.getParameterName());
    }





    /**
     * 拦截未知的运行时异常
     */
    @ExceptionHandler(RuntimeException.class)
    public Result handleRuntimeException(RuntimeException e, HttpServletRequest request)
    {
        String requestURI = request.getRequestURI();
        log.error("请求地址'{}',发生运行时异常.", requestURI, e);
        return Result.error("服务器发生未预料到的运行时异常："+e.getMessage());
    }

    /**
     * 系统异常
     */
    @ExceptionHandler(Exception.class)
    public Result handleException(Exception e, HttpServletRequest request)
    {
        String requestURI = request.getRequestURI();
        log.error("请求地址'{}',发生系统异常.", requestURI, e);
        return Result.error("服务器发生未预料到的系统异常："+e.getMessage());
    }





}
